/*
 * 
 * 
 * 
 */
package com.dyava.commons.image;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 图像工具
 */
public class ImageUtils {

	public static Color TRANSPARENT = new Color(0, 0, 0,0);//透明色

   
    public static String IMAGE_TYPE_GIF = "gif";// 图形交换格式
    public static String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组
    public static String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap（位图）的简写，它是Windows操作系统中的标准图像文件格式
    public static String IMAGE_TYPE_PNG = "png";// 可移植网络图形
    public static String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop


   

    private static int getType(String imageType){
    	if(IMAGE_TYPE_PNG.equalsIgnoreCase(imageType)){
    		return BufferedImage.TYPE_INT_ARGB;
    	}else{
    		return BufferedImage.TYPE_INT_RGB;
    	}
    }
    
    private static Color getFillColor(String imageType){
    	if(IMAGE_TYPE_PNG.equalsIgnoreCase(imageType)){
    		return TRANSPARENT;
    	}else{
    		return Color.WHITE;
    	}
    }
    
/**
 * 按比例缩放
 * @param srcImage 原图数据
 * @param scale    缩放比例
 * @param toImageType  目标图格式
 * @return   目标图数据
 * @throws IOException
 */
    public final static byte[] scaleByRate(byte[] srcImage, double scale ,String toImageType) throws IOException {
        BufferedImage src = ImageIO.read(new ByteArrayInputStream(srcImage)); // 读入文件
        int width = src.getWidth(); // 得到源图宽
        int height = src.getHeight(); // 得到源图长
        width = (int)(width * scale);
        height = (int)(height * scale);
        Image image = src.getScaledInstance(width, height,
                Image.SCALE_DEFAULT);
        BufferedImage tag = new BufferedImage(width, height,
        		getType(toImageType));
        Graphics g = tag.getGraphics();
        g.drawImage(image, 0, 0, null); // 绘制缩小后的图
        g.dispose();
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write(tag, toImageType, osm);// 输出到文件流
        return osm.toByteArray();
    }


   /**
    * 按高度和宽度缩放
    * @param srcImage
    * @param height
    * @param width
    * @param fill
    * @param toImageType
 * @throws IOException
    */
    public final static byte[] scaleByValue(byte[] srcImage , int width,int height,  boolean fill,String toImageType) throws IOException {
        double ratio = 0.0; // 缩放比例
        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImage));
        Image itemp = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        // 计算比例
        if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
            if (bi.getHeight() > bi.getWidth()) {
                ratio = (new Integer(height)).doubleValue()
                        / bi.getHeight();
            } else {
                ratio = (new Integer(width)).doubleValue() / bi.getWidth();
            }
            AffineTransformOp op = new AffineTransformOp(AffineTransform
                    .getScaleInstance(ratio, ratio), null);
            itemp = op.filter(bi, null);
        }
        if (fill) {//补白
            BufferedImage image = new BufferedImage(width, height,
            		getType(toImageType));
            Graphics2D g = image.createGraphics();
            g.setColor(getFillColor(toImageType));
            g.fillRect(0, 0, width, height);
            if (width == itemp.getWidth(null))
                g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                        itemp.getWidth(null), itemp.getHeight(null),
                        getFillColor(toImageType), null);
            else
                g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                        itemp.getWidth(null), itemp.getHeight(null),
                        getFillColor(toImageType), null);
            g.dispose();
            itemp = image;
        }
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write((BufferedImage) itemp, toImageType,osm);
        return osm.toByteArray();
    }
    
   /**
    * 按指定起点坐标和宽高切割
    * @param srcImage
    * @param x
    * @param y
    * @param width
    * @param height
    * @param toImageType
 * @throws IOException
    */
    public final static byte[]  cut(byte[] srcImage , int x, int y, int width, int height,String toImageType) throws IOException {
            // 读取源图像
        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImage));
        int srcWidth = bi.getHeight(); // 源图宽度
        int srcHeight = bi.getWidth(); // 源图高度
        if (srcWidth > 0 && srcHeight > 0) {
            Image image = bi.getScaledInstance(srcWidth, srcHeight,
                    Image.SCALE_DEFAULT);
            // 四个参数分别为图像起点坐标和宽高
            // 即: CropImageFilter(int x,int y,int width,int height)
            ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
            Image img = Toolkit.getDefaultToolkit().createImage(
                    new FilteredImageSource(image.getSource(),
                            cropFilter));
            BufferedImage tag = new BufferedImage(width, height, getType(toImageType));
            Graphics g = tag.getGraphics();
            g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图
            g.dispose();
            // 输出为文件
            ByteArrayOutputStream osm = new ByteArrayOutputStream();
            ImageIO.write(tag, toImageType, osm);
            return osm.toByteArray();
        }else{
        	throw new IOException("长宽不对");
        }
    }

    /**
     * 图像类型转换
     * @param srcImage
     * @param toImageType
     * @throws IOException
     */
    public final static byte[]  convert(byte[] srcImage,String toImageType ) throws IOException {
        BufferedImage src = ImageIO.read(new ByteArrayInputStream(srcImage));
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write(src, toImageType, osm);
        return osm.toByteArray();
    }

    /**
     * 彩色转黑白
     * @param srcImage
     * @param toImageType
     * @return
     * @throws IOException
     */
    public final static byte[]  gray(byte[] srcImage ,String toImageType) throws IOException {
        BufferedImage src = ImageIO.read(new ByteArrayInputStream(srcImage));
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        ColorConvertOp op = new ColorConvertOp(cs, null);
        src = op.filter(src, null);
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write(src,toImageType, osm);
        return osm.toByteArray();
    }

    /**
     * 给图片添加文字水印
     * @param srcImage
     * @param pressText
     * @param fontName
     * @param fontStyle
     * @param color
     * @param fontSize
     * @param x
     * @param y
     * @param alpha
     * @param toImageType
     * @return
     * @throws IOException
     */
    public final static byte[]  pressText(byte[] srcImage, 
    		String pressText, String fontName,
            int fontStyle, Color color, int fontSize,int x,
            int y, float alpha,String toImageType) throws IOException {
        Image src = ImageIO.read(new ByteArrayInputStream(srcImage));
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        BufferedImage image = new BufferedImage(width, height,
                getType(toImageType));
        Graphics2D g = image.createGraphics();
        g.drawImage(src, 0, 0, width, height, null);
        g.setColor(color);
        g.setFont(new Font(fontName, fontStyle, fontSize));
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                alpha));
        // 在指定坐标绘制水印文字
        g.drawString(pressText, (width - (getLength(pressText) * fontSize))
                / 2 + x, (height - fontSize) / 2 + y);
        g.dispose();
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write((BufferedImage) image, toImageType, osm);// 输出到文件流
        return osm.toByteArray();
    }


    /**
     * 给图片添加文字水印
     * @param srcImage
     * @param pressText
     * @param fontName
     * @param fontStyle
     * @param color
     * @param fontSize
     * @param x
     * @param y
     * @param alpha
     * @param toImageType
     * @return
     * @throws IOException
     */
    public final static byte[]  pressText2(byte[] srcImage ,
    		String pressText, String fontName, int fontStyle, Color color, int fontSize, int x,
            int y, float alpha,String toImageType) throws IOException {
        Image src = ImageIO.read(new ByteArrayInputStream(srcImage));
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        BufferedImage image = new BufferedImage(width, height,
                getType(toImageType));
        Graphics2D g = image.createGraphics();
        g.drawImage(src, 0, 0, width, height, null);
        g.setColor(color);
        g.setFont(new Font(fontName, fontStyle, fontSize));
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                alpha));
        // 在指定坐标绘制水印文字
        g.drawString(pressText, (width - (getLength(pressText) * fontSize))
                / 2 + x, (height - fontSize) / 2 + y);
        g.dispose();
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write((BufferedImage) image, toImageType, osm);
        return osm.toByteArray();
    }


    /**
     * 给图片添加图片水印
     * @param srcImage
     * @param pressImg
     * @param x
     * @param y
     * @param alpha
     * @param toImageType
     * @return
     * @throws IOException
     */
    public final static byte[]  pressImage(byte[] srcImage, 
    		InputStream pressImg ,int x, int y, float alpha,String toImageType) throws IOException {
        Image src = ImageIO.read(new ByteArrayInputStream(srcImage));
        int wideth = src.getWidth(null);
        int height = src.getHeight(null);
        BufferedImage image = new BufferedImage(wideth, height,
                getType(toImageType));
        Graphics2D g = image.createGraphics();
        g.drawImage(src, 0, 0, wideth, height, null);
        // 水印文件
        Image src_biao = ImageIO.read(pressImg);
        int wideth_biao = src_biao.getWidth(null);
        int height_biao = src_biao.getHeight(null);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                alpha));
        g.drawImage(src_biao, (wideth - wideth_biao) / 2,
                (height - height_biao) / 2, wideth_biao, height_biao, null);
        // 水印文件结束
        g.dispose();
        ByteArrayOutputStream osm = new ByteArrayOutputStream();
        ImageIO.write((BufferedImage) image, toImageType,osm);
        return osm.toByteArray();
    }


   
    private final static int getLength(String text) {
        int length = 0;
        for (int i = 0; i < text.length(); i++) {
            if (new String(text.charAt(i) + "").getBytes().length > 1) {
                length += 2;
            } else {
                length += 1;
            }
        }
        return length / 2;
    }
}